﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Runtime.Serialization;
using System.Web.SessionState;

namespace Timesheet.Common
{
	/// <summary>
	/// Singleton class for manage Session data
	/// </summary>
	public class SessionHelper
	{
		#region SessionHelper Instance ID
		private int _SessionHelperInstanceID;
		public int SessionHelperInstanceID { get { return _SessionHelperInstanceID; } }
		#endregion

		#region Singleton pattern implementation
		//protected HttpSessionState Session;
		private static SessionHelper _SessionHelperInstance;

		private SessionHelper() 
		{ 
			//session = HttpContext.Current.Session;
			_SessionHelperInstanceID = (new Random()).Next(1000);
		}

		public static SessionHelper GetSessionHelper()
		{
			if (_SessionHelperInstance == null)
			{
				_SessionHelperInstance = new SessionHelper();
			}

			return _SessionHelperInstance;
		}

		/// <summary>
		/// Gets the current session.
		/// </summary>
		protected HttpSessionState Session
		{
			get { return HttpContext.Current.Session; }
		}
		#endregion

		#region Basic types - string,byte,int,long,float,double,decimal,DateTime,TimeSpan
		public void AddStringValueToSession(string key, string value)
		{
			AddSession(key, value);
		}

        public void AddListStringValueToSession(string key, List<string> value) 
        {
            AddSession(key, value);
        }

		public void AddByteToSession(string key, byte? value)
		{
			AddSession(key, value);
		}

		public void AddIntValueToSession(string key, int? value)
		{
			AddSession(key, value);
		}

        public void AddListIntValueToSession(string key, List<int> value)
        {
            AddSession(key, value);
        }

		public void AddLongToSession(string key, long? value)
		{
			AddSession(key, value);
		}

		public void AddFloatValueToSession(string key, float? value)
		{
			AddSession(key, value);
		}

		public void AddDoubleValueToSession(string key, double? value)
		{
			AddSession(key, value);
		}

		public void AddDecimalValueToSession(string key, decimal? value)
		{
			AddSession(key, value);
		}

		public void AddBoolValueToSession(string key, bool? value)
		{
			AddSession(key, value);
		}

		public void AddDateTimeValueToSession(string key, DateTime? value)
		{
			AddSession(key, value);
		}

		public void AddTimeSpanValueToSession(string key, TimeSpan? value)
		{
			AddSession(key, value);
		}

		public string GetStringValueFromSession(string key)
		{
			return GetSession(key) as string;
		}

        public List<string> GetListStringValueFromSession(string key)
        {
            return GetSession(key) as List<string>;
        }

        public byte? GetByteValueFromSession(string key)
		{
			return (byte?)GetSession(key);
		}
		public int? GetIntValueFromSession(string key)
		{
			return (int?)GetSession(key);
		}

		public long? GetLongValueFromSession(string key)
		{
			return (long?)GetSession(key);
		}

		public float? GetFloatValueFromSession(string key)
		{
			return (float?)GetSession(key);
		}

		public double? GetDoubleValueFromSession(string key)
		{
			return (double?)GetSession(key);
		}

		public decimal? GetDecimalValueFromSession(string key)
		{
			return (decimal?)GetSession(key);
		}

		public bool? GetBoolValueFromSession(string key)
		{
			return (bool?)GetSession(key);
		}

		public DateTime? GetDateTimeValueFromSession(string key)
		{
			return (DateTime?)GetSession(key);
		}

		public TimeSpan? GetTimeSpanValueFromSession(string key)
		{
			return (TimeSpan?)GetSession(key);
		}
		#endregion

		#region User-defined type
		/// <summary>
		/// All non-basic types object must implement the interface ISerializable to best manage session data in load balancing environment
		/// </summary>
		/// <param name="sessionKey"></param>
		/// <param name="serializableObject">user defined object that has implement </param>
		public void AddSerializableUserDefinedTypeToSession(string sessionKey, ISerializable serializableObject)
		{
			Session[sessionKey] = serializableObject;
		}

        public object GetSerializableUserDefinedTypeFromSession(string sessionKey)
		{
			if (Session[sessionKey] != null)
			{
				return Session[sessionKey];
			}
			else
			{
				return null;
			}
		}

		/// <summary>
		/// All non-basic types object must implement the interface ISerializable to best manage session data in load balancing environment
		/// </summary>
		/// <param name="sessionKey"></param>
		/// <param name="serializableObject">user defined object that has implement </param>
		public void AddListSerializableUserDefinedTypeToSession(string sessionKey, IEnumerable<ISerializable> serializableObjects)
		{
			Session[sessionKey] = serializableObjects;
		}
		#endregion

		#region Others
		public void Abandon()
		{
			Session.Abandon();
		}

		public void Clear()
		{
			Session.Clear();
		}
		#endregion

		#region Private Methods
		private void AddSession(string key, object value)
		{
			Session[key] = value;
		}

		private object GetSession(string key)
		{
			var value = Session[key];
			if (value != null)
				return value;
			else
				return null;
		}
		#endregion
	}    
}
